package com.elvis.chat.utils.add;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Environment;
import android.util.Log;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;

public class AttachmentManager {
    private static final String TAG = AttachmentManager.class.getSimpleName();

    private Map<String, AttachmentInfo> mAttachments = new HashMap<String, AttachmentInfo>();

    private File AttachmentStorageDirectory;

    final MXParser parser;

    private LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<String>();

    private static String BASEDIR = FileUtil.BASEDIR;

    /**
     * Initialize VCardManager.
     */
    public AttachmentManager() {
	// Initialize parser
	parser = new MXParser();

	try {
	    parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
	} catch (XmlPullParserException e) {
	    e.printStackTrace();
	}

	// Set VCard Storage
	AttachmentStorageDirectory = new File(Environment.getExternalStorageDirectory(), BASEDIR + "attchment");
	AttachmentStorageDirectory.mkdirs();
    }

    /**
     * Adds a jid to lookup vCard.
     * @param jid the jid to lookup.
     */
    private void addToQueue(String jid) {
	if (!queue.contains(jid)) {
	    queue.add(jid);
	}
    }

    /**
     * Returns the Avatar in the form of an <code>Bitmap</code>.
     * @param vcard the vCard containing the avatar.
     * @return the Bitmap or null if no avatar was present.
     */
    public static Bitmap getMediaBitmap(AttachmentInfo Attachment) {
	// Set avatar
	byte[] bytes = Attachment.getBinval();

	if (bytes != null) {
	    Bitmap bm = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
	    return scaleBitmap(bm, 40, 40);
	}
	return null;
    }

    /**
     * Returns the scale bitmap.
     * @param bm the need scale bitmap
     * @param newWidth the bitmap new width.
     * @param newHeight the bitmap new height.
     * @return the new bitmap.
     */
    public static Bitmap scaleBitmap(Bitmap bm, int newWidth, int newHeight) {
	int width = bm.getWidth();
	int height = bm.getHeight();
	float scaleWidth = ((float) newWidth) / width;
	float scaleHeight = ((float) newHeight) / height;
	Matrix matrix = new Matrix();
	matrix.postScale(scaleWidth, scaleHeight);
	return Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
    }

    /**
     * Scales an image to the preferred avatar size.
     * @param icon the icon to scale.
     * @return the scaled version of the image.
     */
    public static Bitmap scale(Bitmap icon) {
	if (icon.getHeight() > 64 || icon.getWidth() > 64) {
	    icon = scaleBitmap(icon, 64, 64);
	}

	return icon;
    }

    public static void outputFile(Bitmap icon, File file, String outputFormatString) {
	Bitmap.CompressFormat mOutputFormat = Bitmap.CompressFormat.PNG;
	if (outputFormatString != null)
	    mOutputFormat = Bitmap.CompressFormat.valueOf(outputFormatString);

	FileOutputStream fOut = null;
	try {
	    fOut = new FileOutputStream(file);
	    icon.compress(mOutputFormat, 100, fOut);
	} catch (FileNotFoundException e) {
	    e.printStackTrace();
	} finally {
	    try {
		fOut.flush();
	    } catch (IOException e) {
		e.printStackTrace();
	    }
	    try {
		fOut.close();
	    } catch (IOException e) {
		e.printStackTrace();
	    }
	}
    }

    /**
     * Attempts to load
     * @param jid the content of the message.
     * @return the Attachment if found, otherwise null.
     */
    public AttachmentInfo loadAttachment(String content) {

	try {
	    StringReader read = new StringReader(content);
	    // Otherwise load from file system. 
	    AttachmentProvider provider = new AttachmentProvider();
	    parser.setInput(read);
	    AttachmentInfo Attachment = (AttachmentInfo) provider.parseIQ(parser);

	    return Attachment;
	} catch (Exception e) {
	    Log.e(TAG, "Unable to load Attachment ", e);
	}

	return null;
    }

    public File persistAttachment(String extendMessage) {
	if (extendMessage == null)
	    return null;

	return persistAttachment(loadAttachment(extendMessage));
    }

    /**
     * Persist Attachment information out for caching.
     * @param Attachment the Attachment
     */
    public File persistAttachment(AttachmentInfo Attachment) {
	if (Attachment == null)
	    return null;

	String fileName = Attachment.getFileName();
	File file = new File(AttachmentStorageDirectory, fileName);
	BufferedOutputStream stream = null;
	try {
	    FileOutputStream fstream = new FileOutputStream(file);
	    stream = new BufferedOutputStream(fstream);
	    stream.write(Attachment.getBinval());
	} catch (Exception e) {
	    e.printStackTrace();
	} finally {
	    if (stream != null) {
		try {
		    stream.close();
		} catch (IOException e1) {
		    e1.printStackTrace();
		}
	    }
	}
	return file;
    }

    /**
     * Get Attachment file out for caching.
     * @param Attachment the Attachment
     */
    public File getAttachmentFile(AttachmentInfo Attachment) {
	File file = new File(AttachmentStorageDirectory, Attachment.getFileName());
	return file;
    }

    public static File getFileFromBytes(byte[] b, String outputFile) {
	BufferedOutputStream stream = null;
	File file = null;
	try {
	    file = new File(outputFile);
	    FileOutputStream fstream = new FileOutputStream(file);
	    stream = new BufferedOutputStream(fstream);
	    stream.write(b);
	} catch (Exception e) {
	    e.printStackTrace();
	} finally {
	    if (stream != null) {
		try {
		    stream.close();
		} catch (IOException e1) {
		    e1.printStackTrace();
		}
	    }
	}
	return file;
    }

}
